package org.example;

/**
 * 请设计一个资产管理系统，支持资产增加、借用、归还、统计的功能。每个资产编号是全局唯一的。
 */
//public class AssertSystem {
//    /**
//     * 系统初始化
//     */
//    AssertSystem(){
//
//    }
//
//    /**
//     * 向系统中增加一个编号为 assetsld 的资产如果资产已经存在则直接返回0;否则增加成功，并返回1。
//     * @param assertId 资产编号
//     * @return 添加成功
//     */
//    int addAsserts(int assertId){
//        return -1;
//    }
//
//    /**
//     * 员工 employeeId 借用资产 assetsId:
//     * 如果资产不存在，则直接返回 -1
//     * 如果资产被借用、且未归还，则直接返回 0
//     * 如果资产未被借用，则成功借用并返回 1
//     * @param employeeId 员工号
//     * @param assertsId 资产号
//     * @return 借用结果
//     */
//    int borrowAsserts(int employeeId, int assertsId){
//        return -1;
//    }
//
//    /**
//     * 归还资产 assetsId:
//     * 如果资产不存在，则直接返回 -1
//     * 如果资产未被任何人借用，则直接返回 0
//     * 否则成功归还，并返回1
//     * @param assertId 资产编号
//     * @return
//     */
//    int returnAsserts(int assertId){
//        return -1;
//    }
//
//    /**
//     * 统计当前系统内有借用、且未归还的借用人，并按如下规则
//     * 返回 topNum 个借用人的 employeeId 和末归还资产的数量:
//     * 优先按未归还的数量从大到小排序;若数量相同，再按借用人的employeeId从小到大排序。
//     * 如果人数不足topNum，则按实际人数返回;如果实际人数为0返回空数组 []
//     * @param topNum
//     * @return
//     */
//    int[][] statAsserts(int topNum){
//        return new int [][]{};
//    }
//
//    public static void main(String[] args) {
//        AssertSystem assertSystem = new AssertSystem();
//        assertSystem.addAsserts(1812);//返回1
//        assertSystem.borrowAsserts(99527, 1812);//返回1
//        assertSystem.addAsserts(1812);//返回0
//        assertSystem.statAsserts(2);//返回[[99527,1]]
//        assertSystem.returnAsserts(1812);//返回1
//    }
//}


import java.util.*;

public class AssertSystem {
    // 资产编号 -> 借用人（null 代表未被借出）
    private Map<Integer, Integer> assetMap = new HashMap<>();
    // 借用人 -> 借用中的资产列表
    private Map<Integer, Set<Integer>> employeeAssets = new HashMap<>();

    public AssertSystem() {
    }

    public int addAsserts(int assertId) {
        if (assetMap.containsKey(assertId)) {
            return 0;
        }
        assetMap.put(assertId, null);
        return 1;
    }

    public int borrowAsserts(int employeeId, int assertsId) {
        if (!assetMap.containsKey(assertsId)) {
            return -1;
        }
        if (assetMap.get(assertsId) != null) {
            return 0;
        }
        assetMap.put(assertsId, employeeId);
        employeeAssets.computeIfAbsent(employeeId, k -> new HashSet<>()).add(assertsId);
        return 1;
    }

    public int returnAsserts(int assertId) {
        if (!assetMap.containsKey(assertId)) {
            return -1;
        }
        Integer employeeId = assetMap.get(assertId);
        if (employeeId == null) {
            return 0;
        }
        assetMap.put(assertId, null);
        Set<Integer> assets = employeeAssets.get(employeeId);
        if (assets != null) {
            assets.remove(assertId);
            if (assets.isEmpty()) {
                employeeAssets.remove(employeeId);
            }
        }
        return 1;
    }

    public int[][] statAsserts(int topNum) {
        if (employeeAssets.isEmpty()) return new int[0][];

        List<int[]> statList = new ArrayList<>();
        for (Map.Entry<Integer, Set<Integer>> entry : employeeAssets.entrySet()) {
            int employeeId = entry.getKey();
            int count = entry.getValue().size();
            statList.add(new int[]{employeeId, count});
        }

        // 排序：先按未归还数量降序，再按 employeeId 升序
        statList.sort((a, b) -> {
            if (b[1] != a[1]) return b[1] - a[1];
            return a[0] - b[0];
        });

        int size = Math.min(topNum, statList.size());
        int[][] result = new int[size][2];
        for (int i = 0; i < size; i++) {
            result[i] = statList.get(i);
        }

        return result;
    }

    public static void main(String[] args) {
        AssertSystem assertSystem = new AssertSystem();
        System.out.println(assertSystem.addAsserts(1812)); // 1
        System.out.println(assertSystem.borrowAsserts(99527, 1812)); // 1
        System.out.println(assertSystem.addAsserts(1812)); // 0

        int[][] stats = assertSystem.statAsserts(2);
        for (int[] row : stats) {
            System.out.println(Arrays.toString(row)); // [99527, 1]
        }

        System.out.println(assertSystem.returnAsserts(1812)); // 1
    }
}

